 1.事务机制与可靠性
   
   一提到事务，首先就想到的是关系型数据库中的事务，事务一个典型的特征就是将一
批操作做成原子性的，要么都成功，要么都失败。
   在Flume中一共有两个事务：
   Put事务。在Source到Channel之间
   Take事务。Channel到Sink之间
   从 Source 到 Channel 过程中，数据在 Flume 中会被封装成 Event 对象，也就是一
批 Event ，把这批 Event 放到一个事务中，把这个事务也就是这批event一次性的放
入Channel 中。同理，Take事务的时候，也是把这一批event组成的事务统一拿出来
到sink放到HDFS上。
 
 2.Flume中的 Put 事务
   
   1).事务开始的时候会调用一个 doPut 方法， doPut 方法将一批数据放在putList中；
   putList在向 Channel 发送数据之前先检查 Channel 的容量能否放得下，如
果放不下一个都不放，只能doRollback；
   数据批的大小取决于配置参数 batch size 的值；
   putList的大小取决于配置 Channel 的参数 transaction capacity 的大小，该参数
大小就体现在putList上；(Channel的另一个参数 capacity 指的是 Channel 的容量)；
   2).数据顺利的放到putList之后，接下来可以调用 doCommit 方法，把putList中所有
的 Event 放到 Channel 中，成功放完之后就清空putList；
   在doCommit提交之后，事务在向 Channel 存放数据的过程中，事务容易出问题。
如 Sink取数据慢，而 Source 放数据速度快，容易造成 Channel 中数据的积压，如
果 putList 中的数据放不进去，会如何呢？
   此时会调用 doRollback 方法，doRollback方法会进行两项操作：将putList清空；
抛出 ChannelException异常。source会捕捉到doRollback抛出的异常，然后source
就将刚才的一批数据重新采集，然后重新开始一个新的事务，这就是事务的回滚。

 3.Flume中的 Take 事务
   
   Take事务同样也有takeList，HDFS sink配置有一个 batch size，这个参数决定 Sink
从 Channel 取数据的时候一次取多少个，所以该 batch size 得小于 takeList 的大
小，而takeList的大小取决于 transaction capacity 的大小，同样是channel 中的
参数。
   Take事务流程：事务开始后：
   doTake方法会将channel中的event剪切到takeList中。如果后面接的是HDFS Sink的话
，在把Channel中的event剪切到takeList中的同时也往写入HDFS的IO缓冲流中放一份event
(数据写入HDFS是先写入IO缓冲流然后flush到HDFS)；
   当takeList中存放了batch size 数量的event之后，就会调用doCommit方法，
doCommit方法会做两个操作：
   1).针对HDFS Sink，手动调用IO流的flush方法，将IO流缓冲区的数据写入到HDFS磁盘中；
   2).清空takeList中的数据
   flush到HDFS的时候组容易出问题。flush到HDFS的时候，可能由于网络原因超时导致数据
传输失败，这个时候调用doRollback方法来进行回滚，回滚的时候由于takeList 中还有备份
数据，所以将takeList中的数据原封不动地还给channel，这时候就完成了事务的回滚。
   
   但是，如果flush到HDFS的时候，数据flush了一半之后出问题了，这意味着已经有一半的
数据已经发送到HDFS上面了，现在出了问题，同样需要调用doRollback方法来进行回滚，回滚
并没有“一半”之说，它只会把整个takeList中的数据返回给channel，然后继续进行数据的读写。
这样开启下一个事务的时候容易造成数据重复的问题。
   Flume在数据进行采集传输的时候，有可能会造成数据的重复，但不会丢失数据。
   Flume在数据传输的过程中是否可靠，还需要考虑具体使用Source、Channel、Sink
的类型。
   1).分析Source
   exec Source ，后面接 tail -f ，这个数据也是有可能丢的
   TailDir Source ，这个是不会丢数据的，它可以保证数据不丢失
   2).分析sink
   Hdfs Sink，数据有可能重复，但是不会丢失
   3).最后，分析channel。理论上说：要想数据不丢失的话，还是要用 File channel；
memory channel 在 Flume 挂掉的时候是有可能造成数据的丢失的。
   4).如果使用 TailDir source 和 HDFS sink，所以数据会重复但是不会丢失



   